import {getUid} from '../common';
const cacheWorks={};
/**
 * 创建worker线程, _task属性表示正在执行的任务数, completed属性在完成所有任务时调用
 * @param module require方法返回的module
 * @return {Promise<unknown>} Promise接收在.worker.js文件中导出的方法
 */
function Worker(module){
	const Constructor=module.default;
	const worker=new Constructor();
	const instance=new Promise(function(resolve){
		worker.addEventListener('message',function({data:{type,value}}){
			if(type==='init'){
				const obj={};
				for(let i=0;i<value.length;++i){
					const key=value[i];
					obj[key]=function(...args){
						const uid=getUid();
						try{
							instance.todo();
							worker.postMessage({
								type:'call',
								value:{
									method:key,
									params:args,
									uid,
								}
							});
						}catch(e){
							instance.done();
							throw e;
						}
						return new Promise(function(resolve){
							cacheWorks[uid]=resolve;
						});
					};
				}
				resolve(obj);
			}else if(type==='return'){
				instance.done();
				const {result,uid}=value;
				cacheWorks[uid](result);
				delete cacheWorks[uid];
			}else if(type==='error'){
				instance.done();
				const {uid}=value;
				// eslint-disable-next-line prefer-promise-reject-errors
				cacheWorks[uid](Promise.reject());
				delete cacheWorks[uid];
			}
		});
	});
	instance._task=0;
	Object.defineProperty(instance,'todo',{
		value:function(){
			++this._task;
		}
	});
	Object.defineProperty(instance,'done',{
		value:function(){
			if(--this._task===0&&this.completed){
				this.completed();
			}
		}
	});
	worker.postMessage({
		type:'ready'
	});
	return instance;
}

export default Worker;
